/*
 *
 * Copyright (c) 2021
 * User:Dybala
 * File:AuthenticationInterceptor.java
 * Date:2021/11/08 10:56:08
 */

package com.config.Interceptor;

import com.config.myAnnotation.PassToken;
import com.service.redisService;
import com.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 配置我的拦截器，用于拦截登录请求等。
 */
public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    private redisService redisService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {

//        System.out.println(request.getMethod());
//        response.setHeader("Access-Control-Allow-Origin","*");
////        response.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE");
//        response.setHeader("Access-Control-Max-Age","3600");
//        response.setHeader("Access-Control-Allow-Headers","*");
////        response.setHeader("Access-Control-Allow-Origin", "*");
//        response.setHeader("Access-Control-Allow-Credentials", "true");
//        response.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
//        response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
//        response.setHeader("Access-Control-Allow-Origin", "*");
//        response.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
//        response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
        String requestURI = request.getRequestURI();
//        System.out.println(requestURI);
        if(request.getMethod().equals("OPTIONS")){
            return true;
        }
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        if (requestURI!=null){
            if ("OPTIONS".equals(request.getRequestURI())){
                return false;
            }
        }
        response.setStatus(401);//默认没有权限
        if(requestURI.contains("user")){
            return handle( request,  response,object,"user");
        }else if(requestURI.contains("admin")){
            return handle( request,  response,object,"admin");
        }
        return false;
    }

    boolean handle(HttpServletRequest request, HttpServletResponse response, Object object,String role){
        String token = request.getHeader("token");// 从 http 请求头中取出 token
        // 如果不是映射到方法直接通过

        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
        if (method.isAnnotationPresent(PassToken.class)) {
            response.setStatus(200);
            return true;
        }else{
            //否则就需要校验了
            if(token==null){
//                throw new RuntimeException("无token，请重新登陆");
                return false;
            }
            String tokenKey = "sys:"+role+":token" + token;
            String temp = redisService.get(tokenKey);
            if(temp==null){
                // 如果是空的，要么是没登录，要么是长时间没操作，返回false，进入登录页面
                return false;
            }else{
                String email=JwtUtils.getEmail(token);
                boolean flag = JwtUtils.verify(temp, email);//邮箱保持不变，因此getemail的参数选用原来的
                if(flag){
                    //1.2 没有过期
                    response.setStatus(200);
                    return true;
                }else{
                    //1.3 token过期了但redis没有过期
//                    System.out.println("更新jwt");
                    String sign = JwtUtils.sign(email);//生成新的token
                    redisService.set(tokenKey,sign);//使用原来的key，更改value，这样做就可以不更改前端
                    redisService.expire(tokenKey,2*JwtUtils.EXPIRE_TIME);//设置为两倍过期时间
                }
                response.setStatus(200);
                return true;
            }
        }
    }


    @Override
    public void postHandle(HttpServletRequest httpServletRequest,
                           HttpServletResponse httpServletResponse,
                           Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest,
                                HttpServletResponse httpServletResponse,
                                Object o, Exception e) throws Exception {
    }
}
